/**  
 * @Title ShiroDbRealm.java
 * @date 2016年3月3日 下午2:20:06
 * @Copyright (c) 2016, unibroad.com Inc. All rights reserved.
 */
package com.strugglerz.web.shiro;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.strugglerz.biz.service.ISysAuthService;
import com.strugglerz.biz.service.ISysUserService;
import com.strugglerz.model.common.SysConstants;
import com.strugglerz.model.dalentity.SysResource;
import com.strugglerz.model.dalentity.SysRole;
import com.strugglerz.model.dalentity.SysUser;
import com.strugglerz.model.exception.BizHandleException;


/**
 * @Description 认证,授权数据源
 * @Class 
 * @author 
 * @version V1.0
 */
public class ShiroDbRealm extends AuthorizingRealm {

	private static final Logger LOG = LoggerFactory.getLogger(ShiroDbRealm.class);

	@Autowired
	private ISysUserService<SysUser> sysUserService;

	@Autowired
	private ISysAuthService sysAuthService;

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.apache.shiro.realm.AuthorizingRealm#doGetAuthorizationInfo(org.apache
	 * .shiro.subject. PrincipalCollection)
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SysUser user = (SysUser) principals.fromRealm(getName()).iterator().next();
		if (user == null) {
			return null;
		}

		// 超级管理员用户
		if (StringUtils.equals(user.getName(), SysConstants.SYS_ROOT_USER)) {
			SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
			authorizationInfo.addRoles(sysAuthService.queryAllRoleCodes());
			authorizationInfo.addStringPermissions(sysAuthService.queryAllPermissions());
			return authorizationInfo;
		}
		

		List<SysRole> usrRoles = null;
		try {
			usrRoles = sysAuthService.queryUserRoles(user.getId());
		} catch (Exception e) {
			LOG.error("doGetAuthorizationInfo exception", e);
		}

		if (!CollectionUtils.isEmpty(usrRoles)) 
		{
			List<String> usrPerminssions = null;
			List<Integer> usrRoleIds = null;
			SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
			List<String> usrRoleCodes = new ArrayList<String>(usrRoles.size());
			usrRoleIds = new ArrayList<Integer>(usrRoles.size());
			List<SysResource> resources = null;

			Iterator<SysRole> roleItr = usrRoles.iterator();
			SysRole sysRole = null;
			while (roleItr.hasNext()) {
				sysRole = roleItr.next();
				usrRoleCodes.add(sysRole.getCode());
				usrRoleIds.add(sysRole.getId());
			}
			// 设置用户角色集
			authorizationInfo.addRoles(usrRoleCodes);

			try {
				resources = sysAuthService.queryPermissions(usrRoleIds);
			} catch (Exception e) {
				LOG.error("doGetAuthorizationInfo exception", e);
			}
			if (resources != null && resources.size() > 0) {
				usrPerminssions = new ArrayList<String>(resources.size());
				for (SysResource res : resources) {
					usrPerminssions.add(res.getCode());
				}
			}
			// 设置用户权限集
			authorizationInfo.addStringPermissions(usrPerminssions);

			return authorizationInfo;
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.apache.shiro.realm.AuthenticatingRealm#doGetAuthenticationInfo(org.
	 * apache.shiro.authc. AuthenticationToken)
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

		String userName = (String) token.getPrincipal();

		SysUser user = null;
		try {
			user = sysUserService.queryByName(userName);
		} catch (BizHandleException e) {
			LOG.error("查询用户异常,userName=" + userName, e);
		}

		if (user == null) {
			throw new UnknownAccountException();
		}

		// user.getStatus();
		// if (Boolean.TRUE.equals(user.getLocked())) {
		// throw new LockedAccountException(); // 帐号锁定
		// }

		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, user.getPassword(),
				ByteSource.Util.bytes(user.getPassword()), getName());

		return authenticationInfo;
	}

}
